package cool.houge.infra.config;

import com.typesafe.config.Config;
import cool.houge.infra.r2dbc.DefaultR2dbcClient;
import cool.houge.infra.r2dbc.R2dbcClient;
import cool.houge.infra.tx.TxOps;
import io.avaje.inject.Bean;
import io.avaje.inject.Factory;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import jakarta.inject.Inject;

import java.time.Duration;

import static io.r2dbc.spi.ConnectionFactoryOptions.*;

/**
 * @author KK (kzou227@qq.com)
 */
@Factory
public class InfraConfiguration {

  private final Config config;

  @Inject
  public InfraConfiguration(Config config) {
    this.config = config;
  }

  @Bean
  public ConnectionFactory connectionFactory() {
    var url = config.getString("houge.r2dbc.url");
    var user = config.getString("houge.r2dbc.user");
    var password = config.getString("houge.r2dbc.password");

    var options =
        ConnectionFactoryOptions.parse(url)
            .mutate()
            .option(CONNECT_TIMEOUT, Duration.ofSeconds(3))
            .option(STATEMENT_TIMEOUT, Duration.ofSeconds(10))
            .option(USER, user)
            .option(PASSWORD, password)
            .option(Option.valueOf("useServerPrepareStatement"), true)
            .option(Option.valueOf("tcpKeepAlive"), true)
            .option(Option.valueOf("tcpNoDelay"), true)
            .build();
    return ConnectionFactories.get(options);
  }

  @Bean
  public R2dbcClient r2dbcClient(ConnectionFactory connectionFactory) {
    return new DefaultR2dbcClient(connectionFactory);
  }

  @Bean
  public TxOps txOps(ConnectionFactory connectionFactory) {
    return new TxOps(connectionFactory, false);
  }
}
